package net.sourceforge.perforce.ui.internal;

import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sourceforge.perforce.core.IP4TeamProvider;
import net.sourceforge.perforce.core.PerforceException;
import net.sourceforge.perforce.ui.PerforceUIPlugin;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.team.core.RepositoryProvider;


public final class AddToSourceControlRunnable implements IRunnableWithProgress {
  // TODO(rcleveng): Use Multimap
  private Map<RepositoryProvider, List<IResource>> map;

  public AddToSourceControlRunnable(Map<RepositoryProvider, List<IResource>> providerMapping) {
    map = providerMapping;

  }

  @SuppressWarnings("unused")
  // InterruptedException
  public void run(IProgressMonitor monitor) throws InterruptedException, InvocationTargetException {
    try {

      Set<RepositoryProvider> keySet = map.keySet();

      monitor.beginTask("", keySet.size() * 1000); //$NON-NLS-1$
      monitor.setTaskName("Add to Source Control...");

      MultiStatus status =
          new MultiStatus(PerforceUIPlugin.ID, MultiStatus.OK,
              "There were one or more problems perfoming 'Add to Source Control'.", null);

      for (Iterator<RepositoryProvider> it = keySet.iterator(); it.hasNext()
          && !monitor.isCanceled();) {
        IP4TeamProvider provider = (IP4TeamProvider) it.next();

        List<IResource> list = map.get(provider);
        IResource[] providerResources = list.toArray(new IResource[list.size()]);

        IStatus result =
            provider.openForAdd(providerResources, IResource.DEPTH_INFINITE, Policy.subMonitorFor(
                monitor, 1000));
        status.merge(result);
      }

      if (!status.isOK()) {
        throw new InvocationTargetException(new PerforceException(status));
      }
    } catch (PerforceException e) {
      throw new InvocationTargetException(e);
    } finally {
      monitor.done();
    }
  }
}
